import org.lobobrowser.gui._
import org.lobobrowser.main._
import org.lobobrowser.ua._
import scala.collection.immutable._
import java.util.{Date,HashMap,Scanner}
import java.io._
import java.text._
import java.util.regex.Pattern
import java.net.URL

package integration
{
	class Browser 
	{
		//will contain sessions with index mapping
		private var sessions:HashMap[Int,FramePanel] = new HashMap() 
		
		private var numOfSessions 		= 1
		
		private var nextSessionId 		= 0
		
		private var curActiveSession	= 1
		
		private var homeURL 			= "http://google.com"
			
		// This optional step initializes logging so only warnings
		// are printed out.
		PlatformInit.getInstance().initLogging(false);
	
		// This step is necessary for extensions to work:
		PlatformInit.getInstance().init(false, false);
		
		//first session contain homepage
		var activeSession = new FramePanel()
		activeSession.navigate(homeURL)
		sessions.put(nextSessionId,activeSession)
		nextSessionId = nextSessionId + 1
			
		def newSession():Int =
		{ 
			var fp = new FramePanel()
			fp.addNavigationListener(new NavigationListener()
			{
			  def beforeLocalNavigate(event:NavigationEvent){}
			  def beforeWindowOpen(event:NavigationEvent){}
			  def beforeNavigate(event:NavigationEvent)
			  {
			    addHistory(event.getOriginatingFrame().getCurrentNavigationEntry())
			  }
			  
			})
			sessions.put(nextSessionId,fp)
			nextSessionId = nextSessionId + 1
			numOfSessions  = numOfSessions +1
			return (nextSessionId - 1)
		}
		
		def deleteSession(Id:Int)
		{
			sessions.remove(Id)
		}
		
		//so that GUI can replace previouse session with new
		def setActiveSession(Id:Int):FramePanel =
		{
			var s = sessions.get(Id)
			if (s != null) activeSession  = s
			return s
		}
		
		def canBack():Boolean = 
		{
			return activeSession.canBack()
		}
		
		def back() 
		{
			activeSession.back()
		}
		
		def canForward():Boolean = 
		{
			return activeSession.canForward()
		}
		
		def forward()
		{
			activeSession.forward()
		}
		
		def navigate(url:String)
		{
		  var u:URL = null
		  try 
		  {	
		    u  = new URL(url)
		  }
		  catch 
		  {
		    case e:Exception => u = new URL("http://www.google.com/search?q="+url) 	    
		  }
			
		  activeSession.navigate(u)	  
		}
		
		def reload()
		{
			activeSession.reload()
		}
		
		def home()
		{
			activeSession.navigate(homeURL)
		}
		
		def getHomeURL():String = 
		{
			return homeURL
		}
		
		def setHomeURL(url:String)
		{
			homeURL = url
		}
		
		def getStatus():String =
		{
			activeSession.getStatus()
		}
		
		def getUrl():String =
		{
			return activeSession.getCurrentNavigationEntry().getUrl().toString()
		}
		
		//for dual display
		def getDualContent(anotherSessionId:Int):FramePanel = 
		{
			var s = sessions.get(anotherSessionId)
			return s
		}
		
		//general text manipulation functions
		def appendEntryTofile(entry:NavigationEntry,file:String)
		{
			var fw:FileWriter = new FileWriter(file,true)
			var s = "("+entry.getTitle()+")"+"  "+"("+entry.getUrl()+")"+"\n" 
			fw.write(s)
			fw.close()
		}
		
		def parseLine(line:String,numOfTokens:Int):Array[String] = 
		{
				var arr = new Array[String](numOfTokens)
				var reg = ""
				var i = 0
				
				//creating pattern
				while(i < numOfTokens - 1)
				{
					reg+="\\(("+".+"+")\\)"+"\\s\\s"
				}
				reg+="\\(("+".+"+")\\)"
				
				var p  = Pattern.compile(reg)
				var m = p.matcher(line)
				if (m.matches())
				{
					i = 0
					while(i < numOfTokens)
					{
						arr(i) = m.group(i+1)
					}
				}
				return arr
		}
		
		
		//bookmarks
		def addBookmark()
		{
			appendEntryTofile(activeSession.getCurrentNavigationEntry(),"Bookmarks")
		}
		
		def getBookmarks():List[(String,String)] = 
		{
			var l:List[(String,String)] = List()
			var scan = new Scanner(new FileReader("Bookmarks"))
			while (scan.hasNextLine())
			{
			  var line = scan.nextLine()
			  var a = parseLine(line,2)
			  l:+=(a(0),a(1))
			}
			return l
		}
		
		//history
		def addHistory(entry:NavigationEntry)
		{	
			var d = new Date()
			var sdf = new SimpleDateFormat("dd.MM.yyyy 'at' HH:mm:ss")
			var fw:FileWriter = new FileWriter("History",false)
			var s = sdf.format(d)
			fw.write(s)
			fw.close()
			appendEntryTofile(entry,"History")
		}
		
		def getHistory():List[(String,String,String)] = 
		{
			var l:List[(String,String,String)] = List()
			var scan = new Scanner(new FileReader("Bookmarks"))
			var count = 0
			while (scan.hasNextLine() && (count < 100))
			{
			  count+=1
			  var line = scan.nextLine()
			  var a = parseLine(line,3)
			  l:+=(a(0),a(1),a(2))
			}
			return l
		}
		
	}
}